/**
 * #info
 *@author   wuwg
 *@createTime    2018/03/20
 *@updateTime    2018/05/29
 *@description   tree-node  component 树节点组件
 */
import config from '../../../../config/config.js'

// components
import atyCollapseTransition from '../../../base/collapse-transition.js'
//  prefix
const prefixCls = config.prefix + '-tree-node'
// module
export default {
  name: prefixCls,
  components: { atyCollapseTransition },
  inject: ['tree'],
  props: {
    /**
     * #property
     *
     * @name    index
     * @cn      索引值
     * @group   数据
     * @type    string
     * @bind    must
     * @description 当前树节点，在整个树数据的下标路径，通过这个下标可以找父级数据
     */
    index: {
      type: null
    },
    /**
     * #property
     *
     * @name    treeNodeData
     * @cn      树节点的数据
     * @group   数据
     * @type    object
     * @bind    must
     * @description 树节点的数据
     */
    treeNodeData: {
      type: Object,
      default () {
        // 数据中的字段， id 和name 必须，其他的为可选参数
        return {
          /*
           * id:'asdasd' , // 数节点的唯一标识符
           * name:'张三' ,// 名称
           * open:true ,// boolean  默认是否展开,
           * leaf:false ,// boolean  是否叶子节点,
           * showCheck:false ,// boolean  是否显示checkbox,
           * disabled:true ,// boolean  是否禁用,
           * leaf:true , // boolean  是否是叶子节点
           * children:[] ,// 子节点
           * checked:false ,// 默认是否被选中
           * icon:'./images/a.png'  // 图标
           */
        }
      }
    },
    /**
     * #property
     *
     * @name    showCheckbox
     * @cn      是否显示多选框
     * @group   控制
     * @type    boolean
     * @value   false
     * @description 是否显示多选框,默认为false
     */
    showCheckbox: {
      type: Boolean,
      default: false
    },
    /**
     * #property
     *
     * @name    showIcon
     * @cn      是否显示图标
     * @group   控制
     * @type    boolean
     * @value   false
     * @description 是否显示图标,默认为false
     */
    showIcon: {
      type: Boolean,
      default: false
    },
    /**
     * #property
     *
     * @name    canMendName
     * @cn      是否可以修改名称
     * @group   控制
     * @type    boolean
     * @value   false
     * @description 是否可以修改名称,默认为false
     */
    canMendName: {
      type: Boolean,
      default: false
    },
    /**
     * #property
     *
     * @name    cascade
     * @cn      级联选择
     * @group   控制
     * @type    boolean
     * @value   false
     * @description 复选框多选时，是否关联子节点选中
     */
    cascade: {
      type: Boolean,
      default: false
    },
    /**
     * #property
     *
     * @name    connectParent
     * @cn      关联父级选中
     * @group   控制
     * @type    boolean
     * @value   false
     * @description 复选框多选时，是否关联父级选中,默认为false
     */
    connectParent: {
      type: Boolean,
      default: false
    },
    /**
     * #property
     *
     * @name    lazyLoad
     * @cn      是否可以懒加载数据
     * @group   加载
     * @type    boolean
     * @false   false
     * @description 是否可以懒加载数据,默认为false
     */
    lazyLoad: {
      type: Boolean,
      default: false
    },

    /**
     * #property
     *
     * @name    draggable
     * @cn      是否可以拖拽
     * @type    boolean
     * @value   false
     * @description 是否可以拖拽,默认为false
     */
    draggable: {
      type: Boolean,
      default: false
    },
    /**
     * #property
     *
     * @name    parent
     * @cn      当前节点的父节点
     * @group   数据
     * @type    string
     * @bind    must
     * @description  当前节点的父节点
     */
    parent: {
      type: null
    }
  },
  data () {
    return {
      currentName: this.treeNodeData.name,
      // 当然vm对象
      currentVm: this,
      // 是否展开
      open: false,
      // 是否获得焦点
      isFocus: false,
      // 节点名字
      treeNodeName: '',
      // 是否显示input
      showInput: false,
      // 复选框是否选中
      checked: false,
      // 图标加载状态
      loadIconStatus: 0, // 0表示未加载默认状态，１表示加载成功，２表示加载失败
      // 是否显示加载图标
      showLoadingIcon: false,
      // 隐藏trigger,  默认false, 不隐藏
      hideTrigger: false,
      // 是否可以拖拽
      currentDraggable: this.draggable,
      // 是否禁用
      disabled: this.treeNodeData.disabled
    }
  },

  watch: {
    'treeNodeData.name' (newVal) {
      if (newVal) {
        this.currentName = newVal
      }
    },
    'treeNodeData.disabled' (newVal) {
      this.disabled = newVal
    }
  },
  computed: {
    currentNameText () {
      return this.currentName ? this.currentName.replace(/<[^>]*>/g, '') : ''
    },
    wrapClass () {
      return [
        prefixCls
      ]
    },
    treeContentClass () {
      return [
        prefixCls + '-content']
    },
    headClass () {
      return [
        prefixCls + '-hd',
        {
          extend: this.open,
          disabled: this.disabled,
          isFocus: this.isFocus,
          select: this.index == this.tree.hoverNode.index && this.tree.treeDragLineStyle.display == 'none',
          active: this.treeNodeData.id == this.tree.currentActiveId
        }
      ]
    },
    headStyle() {
      const style = {}
      if (this.treeNodeData.disabled && this.tree.canSelectDisabled) {
        style.cursor = 'pointer'
      }
      return style
    },
    iconClass () {
      return [
        prefixCls + '-icon',
        {
          [prefixCls + '-icon-success']: this.loadIconStatus == 1,
          [prefixCls + '-icon-error']: this.loadIconStatus == 2
        }
      ]
    },
    triggerClass () {
      return [
        prefixCls + '-trigger',
        {
          hide: this.showLoadingIcon
        }
      ]
    },
    loadingWrapClass () {
      return [
        prefixCls + '-loading',
        {
          show: this.showLoadingIcon
        }
      ]
    },
    loadingClass () {
      return [
        config.prefix + '-icon',
        config.prefix + '-icon-load-c',
        config.prefix + '-load-loop'
      ]
    },
    nameClass () {
      return [
        prefixCls + '-name',
        {
          hide: this.showInput
        }
      ]
    },
    checkboxClass () {
      return [
        prefixCls + '-checkbox'
      ]
    },
    inputClass () {
      return [
        prefixCls + '-input',
        {
          show: this.showInput
        }
      ]
    },
    // 显示trigger元素
    hasTrigger () {
      //  console.log( this.treeNodeData.children && this.treeNodeData.children.length)
      return this.treeNodeData.leaf !== undefined ? !this.treeNodeData.leaf
        : (this.treeNodeData.children && this.treeNodeData.children.length || this.lazyLoad && !this.hideTrigger)
    },
    // 显示trigger元素
    hasLoading () {
      return this.treeNodeData.children && this.treeNodeData.children.length == 0 && this.lazyLoad
    },
    // 当前节点是否显示多选框
    currentShowCheckBox () {
      if (this.showCheckbox === false) {
        return false
      }
      if (this.treeNodeData.showCheck !== undefined) {
        return this.treeNodeData.showCheck
      }
      if (this.tree.onlyLeaf) {
        return this.cascade ? true : !this.hasTrigger
      }
      return this.showCheckbox
    }
  },

  methods: {
    // 切换
    toggle: function (event) {
      this.open = !this.open
      this.$nextTick(() => {
        // 如果展开触发展开事件
        if (this.open) {

          // 添加子数据
          this.addChildren()
          /**
           * #event
           *
           * @name    expand
           * @param   treeNodeData    当前的树节点数据
           * @param   treeNode    当前的树节点
           * @param   event    event对象
           * @body    console.log("展开树！");
           * @description    树展开时触发
           */
          this.tree.$emit('expand', this.treeNodeData, this, event)
        } else {
          /**
           * #event
           *
           * @name    collapse
           * @param   treeNodeData    当前的树节点数据
           * @param   treeNode       当前的树节点
           * @param   event    event对象
           * @body    console.log("闭合树！");
           * @description    树闭合时触发
           */
          this.tree.$emit('collapse', this.treeNodeData, this, event)
        }
      })
    },
    /**
     * @description 点击展开收起按钮，如果没有子集了，并且支持lazyLoad才会去添加子元素
     */
    addChildren: function (getAllChild) {
      // 如果支持懒加载
      // if (this.lazyLoad) { // 前端实现懒加载了 2019-11-12
        // 先判断children， 如果不存在 children,先添加 children=[]; 如果不是数组，那也得变成数组
        if (Artery.type(this.treeNodeData.children) != 'array') {
          this.$set(this.treeNodeData, 'children', [])
        }
        // 如果数组数据长度为0，那么就应该触发懒加载
        if (this.treeNodeData.children.length == 0) {
          // 显示加载图标
          this.showLoadingIcon = true
          // 加载数据
          this.tree.requestTreeData(this.treeNodeData.id, newData => {
            // 添加子数据
            this.addChild(newData)
          }, this.treeNodeData, getAllChild)
        }
      // }
    },
    // 添加数据
    addChild: function (newData) {
      // 隐藏加载图标
      this.showLoadingIcon = false
      if (!newData) {
        if (this.treeNodeData.open !== true) { // 如果用户没有强行设置open属性，则给设置为false。。否则不改变用户给定的true
          this.open = false
        }
        // console.warn('子节点数据不合法: ' + newData)
        return
      }
      if (!Array.isArray(newData)) {
        newData = [newData]
      }
      //  如果新加载的数据长度为0，那么久应该隐藏 trigger
      if (newData.length == 0) {
        this.hideTrigger = true
      } else {
        this.$set(this.treeNodeData, 'children', newData)
      }
    },
    // 点击选中当前的节点
    clickSelect: function (event) {
      // 隐藏焦点
      this.tree.hideFocus()
      // 如果是disabled （禁用）直接返回
      if (this.treeNodeData.disabled && !this.tree.canSelectDisabled) {
        return
      }
      /*
       * 如果当前激活的id不等于本条数据id，那么就需要处理
       * 这里如果同一个节点多次点击，不触发事件，所以这里先注释掉
       * if(this.tree.currentActiveId!==this.treeNodeData.id){
       * 设置选中
       */
      this.tree.setActiveId(this.treeNodeData.id)
      /**
       * #event
       *
       * @name    select
       * @param   treeNodeData    当前的树节点数据
       * @param   treeNode       当前的树节点
       * @param   event    event对象
       * @body    console.log("选中树节点！");
       * @description    选中树节点时触发
       */
      this.tree.$emit('select', this.treeNodeData, this, event)
      // }
      /**
       * @description  点击条目失去焦点
       */
      this.isFocus = false
    },
    // 用户开始拖动元素时触发
    dragstart (event) {
      // 隐藏焦点
      this.tree.hideFocus()
      // 只有当可拖动,而且没有禁用的才执行下面的代码
      if (this.currentDraggable && !this.disabled) {
        //  console.log('dragstart')
        /**
         * “none”：不能把拖动的元素放在这里。这是除文本框之外所有元素的默认值。 (光标显示禁用)
         * “move”：应该把拖动的元素移动到放置目标。 （光标是箭头）
         * “copy”：应该把拖动的元素复制到放置目标。 （光标是箭头和+号）
         * “link”：表示放置目标会打开拖动的元素（但拖动的元素必须是一个链接，有URL）。 （光标是箭头和 跳转箭头）
         */
        /*
         * 在把元素拖动到放置目标上时，以上每一个值都会导致光标显示为不同的符号
         * 然而，要怎样实现光标所指示的动作完全取决于你。
         * 换句话说，如果你不介入，没有什么会自动地移动、复制，也不会打开链接。 !important
         */
        event.dataTransfer.dropEffect = 'move'
        // 拖拽效果
        event.dataTransfer.effectAllowed = 'move'
        // 去除默认的提示图片 （默认的提示图片没办法修改样式）
        event.dataTransfer.setDragImage(this.tree.treeDragPreview, 0, 0)
        /*
         * event.dataTransfer.setData("text", event.target.innerHTML);
         * 被拖动的节点
         */
        this.tree.dragNode = this
        /*
         * console.log(this.tree.dragNode)
         * 显示自己的提示框
         */
        this.tree.treeDragContent.innerHTML = this.treeNodeData.name
        // 设置拖动的元素的内容展示的样式
        this.tree.setTreeDragContentStyle(event, true)

        this.tree.dragging = true

        // 触发tree的事件
        this.tree.emitEvent('dragstart', event)
      }
    },
    // 元素正在拖动时触发
    drag (event) {
      // 只有当可拖动,而且没有禁用的才执行下面的代码
      if (this.currentDraggable && !this.disabled) {
        //  console.log('dragend');
        event.preventDefault()
        // 触发tree的事件
        this.tree.emitEvent('drag', event)
      }
    },
    // 用户完成元素拖动后触发
    dragend (event) {
      // 只有当可拖动,而且没有禁用的才执行下面的代码
      if (this.currentDraggable && !this.disabled) {
        //  console.log('dragend');
        event.preventDefault()
        // 隐藏线和内容提示框
        this.tree.hideTreeDragLineAndContent()
        this.tree.emitEvent('dragend', event)
        this.tree.dragging = false
      }
    },
    // 当被鼠标拖动的对象进入其容器范围内时触发此事件
    dragenter (event) {
      // 只有当可拖动,而且没有禁用的才执行下面的代码
      if (this.currentDraggable && !this.disabled && this.tree.dragging) {
        event.preventDefault()
        // 拖放中,经过的节点
        this.tree.hoverNode = this
        this.tree.emitEvent('dragenter', event)
      }
    },
    // 当某被拖动的对象在另一对象容器范围内拖动时触发此事件
    dragover (event) {
      // 只有当可拖动,而且没有禁用的才执行下面的代码
      if (this.currentDraggable && !this.disabled && this.tree.dragging) {
        /*
         *  console.log('dragover');
         * event.dataTransfer.effectAllowed = "none";
         */
        event.preventDefault()
        // 设置拖动的元素的内容展示的样式
        this.tree.setTreeDragContentStyle(event, true)
        // 拖放中,经过的节点
        this.tree.hoverNode = this
        // 计算拖动线的位置
        this.tree.computedTreeDragLinePostion(event, true)
        this.tree.emitEvent('dragover', event)
      }
    },
    // 当被鼠标拖动的对象离开其容器范围内时触发此事件
    dragleave (event) {
      // 只有当可拖动,而且没有禁用的才执行下面的代码
      if (this.currentDraggable && !this.disabled && this.tree.dragging) {
        event.preventDefault()
        // 拖放中,经过的节点
        this.tree.hoverNode = {}
        this.tree.emitEvent('dragleave', event)
      }
    },
    // 在一个拖动过程中，释放鼠标键时触发此事件
    drop (event) {
      // 只有当可拖动,而且没有禁用的才执行下面的代码
      if (this.currentDraggable && !this.disabled && this.tree.dragging) {
        //  console.log('drop');
        event.preventDefault()
        // 隐藏线和内容提示框
        this.tree.hideTreeDragLineAndContent()
        // 放置目标的节点
        this.tree.dropNode = this
        // 放置目标的节点不是被拖动的节点，这时候才能移动
        if (this.tree.dropNode.$el != this.tree.dragNode.$el) {
          // 移动数据
          this.tree.moveData()
        } else {
          console.log('不能移动本身！')
        }
        // hover 节点清空
        this.tree.hoverNode = {}
        this.tree.emitEvent('drop', event)
        // 停止拖拽
        this.tree.dragging = false
      }
    },

    // 图标加载成功
    handleLoadIcon () {
      //  console.log('sunccess')
      this.loadIconStatus = 1
    },
    // 图标加载失败
    loadError () {
      //  console.log('error')
      this.loadIconStatus = 2
    },

    // 双击修改名称
    dblclickMendName () {
      // 如果可以修改名称
      if (this.canMendName) {
        this.treeNodeName = this.treeNodeData.name
        this.showInput = true
        this.$nextTick(() => {
          this.$refs.inputText.focus()
        })
      }
    },
    handleInputEnter (event) {
      this.$refs.inputText.blur()
    },
    // input事件
    handleInput (event) {
      this.treeNodeData.name = this.treeNodeName
      this.currentName = this.treeNodeData.name
      this.showInput = false
      /**
       * #event
       *
       * @name    mend-name
       * @param   treeNodeData    当前的树节点数据
       * @param   treeNode       当前的树节点
       * @param   event    event对象
       * @body
       * @description    选中树节点时触发
       */
      this.tree.$emit('mend-name', this.treeNodeData, this, event)
    },
    // checkbox 事件
    changeCheckbox (event) {
      if (this.disabled) {
        return false
      }
      // 设置当前选中的 id 和 nodes
      this.setCurrentCheckedIdsAndNodes()
      // 如果关联父元素
      if (this.connectParent) {
        if (this.parent) {
          // 触发父元素的check change
          this.parent.$emit('parentChangeCheck', this.checked)
        }
      }
      let checkedIds = this.tree.currentCheckedIds
      if (this.cascade) {
        this.emitChildrenCheckChange(this.checked)
        if (!this.tree.lazyLoad && !this.tree.syncRender) {
          // 非懒加载 && 非同步渲染, 则从原始数据中直接获取需要级联的后代返回给上层
          const rawData = this.tree.getTreeNodeData(this.treeNodeData.id)
          let _this = this
          if (rawData && rawData.children && rawData.children.length) {
            checkedIds = checkedIds.slice(0)
            const fillId = (data) => {
              if (!data || data.length == 0) {
                return
              }
              data.forEach(item => {
                if (_this.checked && !item.disabled) {
                  if (!checkedIds.includes(item.id)) checkedIds.push(item.id)
                } else {
                  const index = checkedIds.indexOf(item.id)
                  if (index > -1) checkedIds.splice(index, 1) // 删除元素
                }
                fillId(item.children)
              })
            }
            fillId(rawData.children)
          }
        }
      }
      /**
       * #event
       *
       * @name    check
       * @param   checked         当前的树节点的选中状态
       * @param   treeNodeData    当前的树节点数据
       * @param   treeNode       当前的树节点
       * @param   currentCheckedIds         当前的树所有选中的节点的id
       * @param   event    event对象
       * @body    console.log("选中树结点！");
       * @description    点击复选框时触发
       */
      this.tree.$emit('check', this.checked, this.treeNodeData, this, checkedIds, event)
    },
    // fillAllChildren (treeNodes, allChildren) {
    //   for (let i = 0; i < treeNodes.length; i++) {
    //     allChildren.push(treeNodes[i].treeNodeData)
    //     this.fillAllChildren(treeNodes[i].$children, allChildren)
    //   }
    // },
    // 设置当前选中的 id 和 nodes
    setCurrentCheckedIdsAndNodes () {
      const _index = this.tree.currentCheckedIds.indexOf(this.treeNodeData.id)
      // 如果选中,但是currentCheckedIds没包含，这时候需要添加进去
      if (this.checked && _index == -1) {
        // 添加选中id
        this.tree.currentCheckedIds.push(this.treeNodeData.id)
        // 添加选中节点
        // this.tree.currentCheckedNodes[this.treeNodeData.id] = this
      }
      // 如果未选中，但是currentCheckedIds中包含了，这时需要从currentCheckedIds中删除，并且删除选中节点
      else if (!this.checked && _index != -1) {
        // 删除数据id
        this.tree.currentCheckedIds.splice(_index, 1)
        // 删除节点
        // delete this.tree.currentCheckedNodes[this.treeNodeData.id]
      }
    },

    // 触发子组件的 check chang 事件
    emitChildrenCheckChange (checked) {
      // 循环所有的子组件
      if (this.$children.length) {
        this.$children.forEach(function (item, index) {
          item.$emit('childrenChangeCheck', checked)
        })
      } else if (this.checked && this.treeNodeData.leaf === false && this.lazyLoad) {
        // 目前没有子节点 && 选中 && 非叶子, 则异步添加上节点
        this.addChildren(true)
      }
    },
    // 判断复选框是否选中
    adjustIsChecked (isInit) {
      const _index = this.tree.currentCheckedIds.indexOf(this.treeNodeData.id)
      //  如果是初始化
      if (isInit) {
        // 如果是选中的，但是currentCheckedIds没包含，那么就需要添加进去
        if (this.checked && _index == -1) {
          // 添加选中id到currentCheckedIds中
          this.tree.currentCheckedIds.push(this.treeNodeData.id)
        }
        // 如果默认没选中，但是 currentCheckedIds中包含了，这时需要将 checked 设置为 true;
        else if (!this.checked && _index != -1) {
          this.checked = true
        }
      } else {
        this.checked = _index != -1
      }

      // // 如果选中
      // if (this.checked) {
      //   this.tree.currentCheckedNodes[this.treeNodeData.id] = this
      // } else {
      //   // 如果在选中上，currentCheckedNodes存在，那么就应该删除
      //   if (this.tree.currentCheckedNodes[this.treeNodeData.id]) {
      //     delete this.tree.currentCheckedNodes[this.treeNodeData.id]
      //   }
      // }
    },
    // 判断该树节点是否被选中
    adjustIsActive () {
      // 如果是选中的，那么this就是当前激活的节点
      if (this.tree.currentActiveId == this.treeNodeData.id) {
        this.tree.currentActiveTreeNode = this
      }
    },
    // 初始化多选框相关功能
    initCheckbox () { // TODO init 初始化connectParent
      const _this = this
      // 如果显示多选框，才需要执行以下代码
      if (this.showCheckbox) {
        // 如果级联,那么复选框应该和父元素的选中状态保持一致
        if (this.cascade && this.parent && !this.disabled) {
          this.checked = this.parent.checked
        }

        // 如果数据中设置了checked这个属性，那么就会以数据中的checked作为值
        else if (this.treeNodeData.checked !== undefined) {
          // 根据数据设置其选中状态
          this.checked = this.treeNodeData.checked
        }
        // 默认进行一次判断
        this.adjustIsChecked(true)
        if (this.checked) {
          this.tree.$emit('check', this.checked, this.treeNodeData, this, this.tree.currentCheckedIds)
        }
        // 绑定自身多选改变事件 （设置选中会用到）
        _this.$on('changeChecked', function () {
          // 判断是否选中
          _this.adjustIsChecked(false)
        })

        // 绑定父元素check改变事件
        _this.$on('parentChangeCheck', function (checked) {
          /*
           * 如果子选中,并且父可选
           */
          if (checked && !this.disabled) {
            // 如果父没选中，那么需要循环遍历子组件
            if (!_this.checked) {
              // 循环所有的子组件，重新判断checked状态
              _this.checked = _this.$children.every(function (item, index) {
                // 如果不显示多选框，或者是禁用，不参与关联内。
                if (!item.currentShowCheckBox || item.disabled) {
                  return true
                } else {
                  // 其他情况直接返回当前的选中状态
                  return item.checked
                }
              })
              if (_this.checked) {
                // 设置当前选中的 id 和 nodes
                _this.setCurrentCheckedIdsAndNodes()
                // 继续告诉父级
                if (_this.parent) {
                  // 触发父元素的check change
                  _this.parent.$emit('parentChangeCheck', _this.checked)
                }
              }
            }
          } else {
            //  如果是选中的那么需要取消选中
            if (_this.checked) {
              _this.checked = false
              // 设置当前选中的 id 和 nodes
              _this.setCurrentCheckedIdsAndNodes()
              // 继续告诉父级
              if (_this.parent) {
                // 触发父元素的check change
                _this.parent.$emit('parentChangeCheck', _this.checked)
              }
            }
          }
        })

        // 绑定子元素check改变事件
        _this.$on('childrenChangeCheck', function (checked) {
          // 如果不显示多选框，或者是禁用，不参与关联内。
          if (!_this.currentShowCheckBox || _this.disabled) {
            return false
          } else if (_this.checked != checked) {
            // 如果子选中
            _this.checked = checked
            // 设置当前选中的 id 和 nodes
            _this.setCurrentCheckedIdsAndNodes()
            //  触发子组件的 check  change 事件
            _this.emitChildrenCheckChange(checked)
          }
        })

        // 绑定子元素销毁后的事件
        _this.$on('childreDestoryed', function () {
          if (_this.$children.length > 0) {
            let _checked = false
            // 循环所有的子组件，重新判断checked状态
            _checked = _this.$children.every(function (item, index) {
              return !!item.checked
            })
            // 如果不相等，说明需要重新复制
            if (_this.checked != _checked) {
              // 如果子选中
              _this.checked = _checked
              // 设置当前选中的 id 和 nodes
              _this.setCurrentCheckedIdsAndNodes()
              // 触发父元素的check change
              if (_this.parent) {
                _this.parent.$emit('parentChangeCheck', _this.checked)
              }
            }
          }
        })
      }
    },
    // 初始化拖拽相关功能
    initDraggAble () {
      // 如果可以拖拽，才需要执行以下代码
      if (this.draggable) {
        // 也就是说。如果数据中设置了  draggable 这个属性，那么就会以数据中的draggable作为最后的值
        if (this.treeNodeData.draggable !== undefined) {
          this.currentDraggable = this.treeNodeData.draggable
        }
      }
    },
    // 初始化基础功能
    init () {
      // 判断是否展开
      this.open = this.treeNodeData.open || false
      if (this.open && !this.lazyLoad) {
        this.addChildren()
      }
      // 绑定单选改变事件
      this.$on('changeActive', function () {
        // 判断是否激活
        this.adjustIsActive()
      })
      // 单选判断
      this.adjustIsActive()
      //  触发树添加树节点事件
      // this.tree.$emit('tree-node-add', this)

      /*
       * @time 2018-06-22
       * @description  暂时不需要选择激活，搜索改成了下拉的形式。后续可能根据实际需要添加。
       * // 判断是否可以过滤
       * if(this.tree.canFilter  && this.tree.currentFilter){
       * var  _parttern=new RegExp(this.tree.currentFilter,'igm');
       * let  _name= this.treeNodeData.name;
       * // 修改名字
       * this.currentName= _name.replace(_parttern,'<em>'+this.tree.currentFilter+'</em>');
       * // 如果匹配才需要添加
       * if(_parttern.test(_name)){
       * this.tree.currentFilterNodes.push(this);
       * }
       *}
       */
    },
    // 解除事件绑定
    unbindEvent () {
      // 解除单选改变事件
      this.$off('changeActive')
      // 如果显示多选框，才需要执行以下代码
      if (this.showCheckbox) {
        // 解除自身多选改变事件
        this.$off('changeChecked')
        // 解除父元素check改变事件
        this.$off('parentChangeCheck')
        // 解除子元素check改变事件
        this.$off('childrenChangeCheck')
        // 解除父级的（子销毁）事件
        this.$off('childreDestoryed')
      }
    }
  },
  created () {
    // 初始化
    this.init()
  },
  beforeMount() {
    // 初始化多选框相关功能
    this.initCheckbox()
    // 初始化拖拽相关功能
    this.initDraggAble()
  },
  beforeDestroy () {
    // 解除事件
    this.unbindEvent()
    // 如果关联父元素
    if (this.connectParent && this.parent) {
      //  触发父级的（子销毁）事件
      this.parent.$emit('childreDestoryed')
    }
    // 触发树的删除树节点事件
    this.tree.$emit('tree-node-destroy', this.treeNodeData.id)
  }
}
